<template>
  <el-container class="widget-edit-container module-edit-container">
    <el-aside class="aside-left">
      <el-card shadow="never" body-class="aside-card-body">
        <template #header>
          <span>
            <svg-icon icon-class="el-set-up" />
            {{ i18nt('designer.componentLib') }}
          </span>
        </template>
        <el-scrollbar class="components-scrollbar" :style="{ height: scrollerHeight + 'px' }" always>
          <ul @dragover="onComponentDragOver">
            <li v-for="component in widgetList" :key="component.type" :class="{
              'field-widget-item': true,
              'field-widget-item-disabled': !designer || component.disabled
            }" :title="component.displayName" :draggable="designer && !component.disabled ? true : false"
              @dblclick="addFieldByDbClick(component)" @dragstart="onComponentDragStart(component, $event)">
              <span><svg-icon :icon-class="component.icon" class-name="color-svg-icon" />{{
                i18nt(`designer.widgetLabel.${component.type}`)
                }}</span>
            </li>
          </ul>
        </el-scrollbar>
      </el-card>
    </el-aside>
    <el-main class="widget-edit-main">
      <el-scrollbar class="widget-designer-scroll" style="height: 488px" always>
        <div class="widget-designer" :style="{ width: canvasWidth + 60 + 'px', height: canvasHeight + 60 + 'px' }">
          <div ref="horizontalRuler" class="ruler horizontal-ruler"></div><!--水平边线 -->
          <div ref="verticalRuler" class="ruler vertical-ruler"></div><!--边线 -->
          <div class="widget-canvas-cantainer">
            <div ref="widgetCanvasRef" class="widget-canvas module-edit-canvas" :style="{
              width: canvasWidth + 'px',
              height: canvasHeight + 'px',
              backgroundColor: widget.options.color
            }" @click="canvasClickHandler" @dragover="onDragOver" @drop="onDrop" @contextmenu.stop="onContextMenu">
              <component :is="getWidgetName(cWidget)" v-for="(cWidget, index) in widgetChildren" :key="cWidget.id"
                :ref="cWidget.id" :field="cWidget" :designer="designer" :settings="settings"
                :parent-list="widgetChildren" :index-of-parent-list="index" :parent-widget="widget" :design-state="true"
                :widget-edit="true" :style="{
                  left: cWidget.options.x + 'px',
                  top: cWidget.options.y + 'px'
                }"></component>
            </div>
          </div>
        </div>
      </el-scrollbar>
    </el-main>
    <el-aside class="aside-right">
      <el-tabs type="card" :style="{ height: settingsPanelHeight + 'px' }">
        <el-tab-pane :label="i18nt('designer.hint.widgetSetting')">
          <el-scrollbar class="property-setting-scrollbar" :style="{ height: scrollerHeight + 'px' }" always>
            <template v-if="selectedWidget">
              <el-form :model="optionModel" size="small" label-position="right" label-width="90px" class="setting-form"
                @submit.prevent>
                <el-collapse v-model="collapseNames" class="setting-collapse">
                  <el-collapse-item v-if="appearancePropList.length > 0" name="1" title="外观">
                    <template v-for="editorName in appearancePropList" :key="editorName">
                      <component :is="editorName" :designer="designer" :selected-widget="selectedWidget"
                        :option-model="optionModel" :disabled="widgetPropDisabled(editorName)"></component>
                    </template>
                  </el-collapse-item>

                  <el-collapse-item v-if="positionSizePropList.length > 0" name="2" title="位置尺寸">
                    <template v-for="editorName in positionSizePropList" :key="editorName">
                      <component :is="editorName" :designer="designer" :selected-widget="selectedWidget"
                        :option-model="optionModel" :disabled="widgetPropDisabled(editorName)" :parent-widget="widget">
                      </component>
                    </template>
                  </el-collapse-item>

                  <el-collapse-item v-if="miscPropList.length > 0" name="3" title="杂项">
                    <template v-for="editorName in miscPropList" :key="editorName">
                      <component :is="editorName" :designer="designer" :selected-widget="selectedWidget"
                        :option-model="optionModel" :disabled="widgetPropDisabled(editorName)"></component>
                    </template>
                  </el-collapse-item>

                  <el-collapse-item v-if="fontPropList.length > 0" name="4" title="字体">
                    <template v-for="editorName in fontPropList" :key="editorName">
                      <component :is="editorName" :designer="designer" :selected-widget="selectedWidget"
                        :option-model="optionModel" :disabled="widgetPropDisabled(editorName)"></component>
                    </template>
                  </el-collapse-item>

                  <el-collapse-item v-if="dataPropList.length > 0" name="3" title="数据">
                    <template v-for="editorName in dataPropList" :key="editorName">
                      <component :is="editorName" :designer="designer" :selected-widget="selectedWidget"
                        :option-model="optionModel" :disabled="widgetPropDisabled(editorName)"></component>
                    </template>
                  </el-collapse-item>

                  <el-collapse-item v-if="eventPropList.length > 0" name="6" title="事件">
                    <template v-for="editorName in eventPropList" :key="editorName">
                      <component :is="editorName" :designer="designer" :selected-widget="selectedWidget"
                        :option-model="optionModel" :disabled="widgetPropDisabled(editorName)"></component>
                    </template>
                  </el-collapse-item>
                </el-collapse>
              </el-form>
            </template>
          </el-scrollbar>
        </el-tab-pane>

        <el-tab-pane label="内部组件" style="padding: 10px 0;overflow-y: auto;" :style="{ height: scrollerHeight + 'px' }">
          <template v-for="(widget2, ind2) in pageWidgetList" :key="widget2.id">
            <div @click="selectNode(ind2)" class="baseNodeCls" :class="{ selectNodeCls: ind2 == seleNodeInd }">
              <div>
                {{ widget2.name }}
              </div>
              <div @click="delNode(ind2)">
                删除
              </div>
            </div>
          </template>
        </el-tab-pane>
      </el-tabs>
    </el-aside>

    <el-dialog v-model="showWidgetEventDialogFlag"
      :title="`${i18nt(`designer.widgetLabel.${selectedWidget && selectedWidget.type}`)}组件${curEventName}编辑`"
      :show-close="true" class="code-editor-dialog small-padding-dialog" append-to-body :close-on-click-modal="false"
      :close-on-press-escape="false" :destroy-on-close="true" draggable>
      <div class="variable-info" v-if="selectedWidget">
    <p>控件ID : {{selectedWidget.options.name}}</p>
    <p >当前函数的通用变量(以下变量只在当前控件的范围有效)</p>
<p>objId : 指的是当前控件的ID（{{ selectedWidget.options.name }}），可以通过函数get_obj_width、get_obj_height、set_obj_width、set_obj_attr_ext1等函数获取和设置控件信息</p>
      <p>value : 当前控件的值</p>
  </div>
      <code-editor ref="ecEditor" v-model="eventHandlerCode" :mode="'lua'" :readonly="false"></code-editor>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="showWidgetEventDialogFlag = false">
            {{ i18nt('designer.hint.cancel') }}</el-button>
            <el-button type="success" @click="handleWidgetPreview">
        {{ i18nt('designer.hint.simulate') }}</el-button>
          <el-button type="primary" @click="saveEventHandler">
            {{ i18nt('designer.hint.confirm') }}</el-button>
        </div>
      </template>
    </el-dialog>
  </el-container>
</template>

<script>
import * as ELECTRON from '@/electron'
import Ruler from '@scena/ruler'
import { widgetList as BFS, moduleWidgetList } from '@/designer/widget-panel/widgetsConfig'
import {
  APPEARANCE_PROPERTIES,
  POSITION_SIZE_PROPERTIES,
  FONT_PROPERTIES,
  DATA_PROPERTIES,
  MISC_PROPERTIES,
  EVENT_PROPERTIES
} from '@/designer/setting-panel/propertyRegister'
import * as CONST from '@/designer/const'
import { useMouseInElement } from '@vueuse/core'
import { ref } from 'vue'
import { translate } from '@/i18n'
import emitter from '@/mixins/emitter'
import { deepClone, generateId } from '@/utils/util'

export default {
  name: 'ModuleWidget',
  componentName: 'ModuleWidget',
  mixins: [emitter],
  provide() {
    return {
      refList: this.widgetRefList,
      getOptionData: () => this.optionData,
      globalModel: {
        formModel: this.formModel
      }
    }
  },
  props: {
    designer: Object,
    settings: Object,
    widget: Object
  },
  setup() {
    const widgetCanvasRef = ref(null)
    const { elementX, elementY, elementWidth, elementHeight } = useMouseInElement(widgetCanvasRef)
    return {
      widgetCanvasRef,
      elementX,
      elementY,
      elementWidth,
      elementHeight
    }
  },
  data() {
    return {
      // 允许作为子组件的组件列表
      widgetList: BFS.filter((widget) => moduleWidgetList.includes(widget.type)).map((config) => {
        // console.log(config)
        return {
          ...config,
          displayName: translate(`designer.widgetLabel.${config.type}`),
          designerId: this.designer?.id || `module-${generateId()}`, // 确保有唯一ID
        }
      }),

      // 滚动条高度
      scrollerHeight: 400,

      collapseNames: ['1', '2', '3', '4', '5', '6'],
      formModel: {},
      widgetRefList: {},
      vRuler: null,
      hRuler: null,

      seleNodeInd: -1,

      showWidgetEventDialogFlag: false,
      eventHandlerCode: '',
      curEventName: '',
      clipboard: null,
      lastPasteTime: 0,
    }
  },
  computed: {
    pageWidgetList() {
      let li = []
      let widgetL = this.widgetChildren
      Object.keys(widgetL).forEach(function (key) {
        li.push({ name: widgetL[key].options.name, checked: false })
      })

      // this.selectedWidget.forEach((item) => {
      //   li.push({name: item.options.name, checked: false})
      // })
      // console.log(li)
      return li
    },
    optionModel() {
      return this.selectedWidget && this.selectedWidget.options
    },
    widgetChildren() {
      return this.widget.widgetList || []
    },
    selectedWidget() {
      return this.designer ? this.designer.selectedWidget : null
    },
    backgroundPositionX() {
      const align = this.widget.options.pngAlign
      if (
        align === CONST.ALIGN_TYPE.LV_ALIGN_TOP_LEFT ||
        align === CONST.ALIGN_TYPE.LV_ALIGN_LEFT_MID ||
        align === CONST.ALIGN_TYPE.LV_ALIGN_BOTTOM_LEFT
      ) {
        return 'left'
      } else if (
        align === CONST.ALIGN_TYPE.LV_ALIGN_TOP_RIGHT ||
        align === CONST.ALIGN_TYPE.LV_ALIGN_RIGHT_MID ||
        align === CONST.ALIGN_TYPE.LV_ALIGN_BOTTOM_RIGHT
      ) {
        return 'right'
      } else {
        return 'center'
      }
    },
    appearancePropList() {
      // console.log('2=====> ')
      // console.log(APPEARANCE_PROPERTIES)

      if (!this.optionModel) {
        return []
      }
      return Object.keys(APPEARANCE_PROPERTIES)
        .filter((prop) => {
          return Object.hasOwn(this.optionModel, prop)
        })
        .map((prop) => {
          return APPEARANCE_PROPERTIES[prop]
        })
    },
    positionSizePropList() {
      if (!this.optionModel) {
        return []
      }
      return Object.keys(POSITION_SIZE_PROPERTIES)
        .filter((prop) => {
          return Object.hasOwn(this.optionModel, prop)
        })
        .map((prop) => {
          return POSITION_SIZE_PROPERTIES[prop]
        })
    },
    fontPropList() {
      if (!this.optionModel) {
        return []
      }
      return Object.keys(FONT_PROPERTIES)
        .filter((prop) => {
          return Object.hasOwn(this.optionModel, prop)
        })
        .map((prop) => {
          return FONT_PROPERTIES[prop]
        })
    },
    dataPropList() {
      if (!this.optionModel) {
        return []
      }
      return Object.keys(DATA_PROPERTIES)
        .filter((prop) => {
          return Object.hasOwn(this.optionModel, prop)
        })
        .map((prop) => {
          return DATA_PROPERTIES[prop]
        })
    },
    miscPropList() {
      if (!this.optionModel) {
        return []
      }
      return Object.keys(MISC_PROPERTIES)
        .filter((prop) => {
          return Object.hasOwn(this.optionModel, prop)
        })
        .map((prop) => {
          return MISC_PROPERTIES[prop]
        })
    },
    eventPropList() {
      if (!this.optionModel) {
        return []
      }
      return Object.keys(EVENT_PROPERTIES)
        .filter((prop) => {
          return Object.hasOwn(this.optionModel, prop)
        })
        .map((prop) => {
          return EVENT_PROPERTIES[prop]
        })
    },
    canvasWidth() {
      if (this.widget.options.scrollType === 2 || this.widget.options.scrollType === 3) {
        return this.widget.options.scrollWidth
      }
      return this.widget.options.width
    },
    canvasHeight() {
      if (this.widget.options.scrollType === 1 || this.widget.options.scrollType === 3) {
        return this.widget.options.scrollHeight
      }
      return this.widget.options.height
    }
  },
  watch: {
    // 监听clipboard变化，同步到全局
  clipboard: {
    handler(newVal) {
      if (newVal && newVal.widget) {
        const parentInstance = this.getParentDesignerInstance();
        if (parentInstance) {
          parentInstance.globalClipboard = deepClone(newVal);
        }
      }
    },
    deep: true
  },
    canvasHeight(newVal, oldVal) {
      if (newVal !== oldVal) {
        this.$nextTick(() => {
          this.reRenderVerticalRuler(newVal)
        })
      }
    },

    selectedWidget(newVal) {
      if (newVal == null) {
        return
      }
      let widgetL = this.widgetChildren
      // console.log(newVal)
      for (let ind in widgetL) {
        if (widgetL[ind].options.name == newVal.options.name) {
          this.seleNodeInd = ind
        }
      }
    },
    canvasWidth(newVal, oldVal) {
      if (newVal !== oldVal) {
        this.$nextTick(() => {
          this.reRenderHorizontalRuler(newVal)
        })
      }
    }
  },
  mounted() {
   console.group('Module组件初始化');
  
  // 保存原始方法引用
  this.originalCopyMethod = this.designer?.copySelectedWidget;
  this.originalPasteMethod = this.designer?.pasteWidget;
  this.originalClipboard = this.designer?.copyWidget || null;
  
  // 重写粘贴方法，使其能够访问全局剪贴板
  if (this.designer) {
    this.designer.pasteWidget = (position, scale = 1) => {
      this.pasteWidgetInModule(position, scale);
    };
  }
  
  console.groupEnd();
  this.logDesignerInfo();
  
  // 添加全局剪贴板同步
  this.syncClipboardFromGlobal();
    this.on$('editEventHandler', (eventParams) => {
      this.editEventHandler(eventParams[0], eventParams[1])
    })  

    this.$emitter.on('widget-drag-end', this.handleDragEnd)

    // this.$emitter.off('pasteWidget')
    //this.$emitter.on('copyWidget', this.copyWidget)
     this.$emitter.on('pasteWidget', this.pasteWidget)

    this.widgetCanvasRef = this.$refs.widgetCanvasRef

    this.reRenderHorizontalRuler(this.canvasWidth)
    this.reRenderVerticalRuler(this.canvasHeight)
    // 新增键盘事件监听器
    window.addEventListener('keydown', this.handleKeyDown)
  },
  unmounted() {
   // 恢复原始粘贴方法
  if (this.designer && this.originalPasteMethod) {
    this.designer.pasteWidget = this.originalPasteMethod;
  }
  
  // 恢复原始复制方法（如果被修改过）
  if (this.designer && this.originalCopyMethod) {
    this.designer.copySelectedWidget = this.originalCopyMethod;
  }
  
  this.$emitter.off('widget-drag-end', this.handleDragEnd)
  this.$emitter.off('pasteWidget', this.pasteWidget)
  
  // 移除键盘事件监听器
  window.removeEventListener('keydown', this.handleKeyDown)
  },
  activated() {
  // Module组件激活时，从全局剪贴板同步
  this.syncClipboardFromGlobal();
  console.log('Module激活，剪贴板已同步');
},

deactivated() {
  // Module组件失活时，确保全局剪贴板有最新数据
  if (this.clipboard && this.clipboard.widget) {
    const parentInstance = this.getParentDesignerInstance();
    if (parentInstance) {
      parentInstance.globalClipboard = deepClone(this.clipboard);
      console.log('Module失活，剪贴板已同步到全局');
    }
  }
},
  methods: {
    syncClipboardFromGlobal() {
    // 获取父组件的全局剪贴板
    const parentInstance = this.getParentDesignerInstance();
    if (parentInstance && parentInstance.globalClipboard) {
      this.clipboard = deepClone(parentInstance.globalClipboard);
      console.log('从全局剪贴板同步成功:', this.clipboard);
    }
  },
  
  getParentDesignerInstance() {
    // 向上查找父组件实例
    let parent = this.$parent;
    while (parent) {
      if (parent.$options.name === 'VFormDesigner') {
        return parent;
      }
      parent = parent.$parent;
    }
    return null;
  },
    // 修改pasteWidgetInModule方法
// 修改pasteWidgetInModule方法，添加尺寸检查
pasteWidgetInModule(position, scale = 1) {
  // 优先使用全局剪贴板
  const parentInstance = this.getParentDesignerInstance();
  const useGlobalClipboard = parentInstance && parentInstance.globalClipboard && 
                            parentInstance.globalClipboard.widget;
  
  const clipboardSource = useGlobalClipboard ? parentInstance.globalClipboard : this.clipboard;
  
  if (!clipboardSource || !clipboardSource.widget) {
    console.warn('No widget to paste - clipboard is null');
    return;
  }
  
  // 创建新的组件实例
  const newWidget = deepClone(clipboardSource.widget);
  const tempId = generateId();
  newWidget.id = newWidget.type.replace(/-/g, '') + tempId;
  
  const lastId = this.designer.getLastId();
  newWidget.options.id = lastId;
  newWidget.options.name = `${newWidget.type}${lastId}`;
  
  if (newWidget.options.userId) {
    newWidget.options.userId = this.designer.getLastUserId();
  }
  
  // 处理子组件
  if (newWidget.widgetList) {
    this.copyWidgetListForModule(newWidget.widgetList, newWidget);
  }
  
  // 获取模块画布信息
  const canvasRect = this.$refs.widgetCanvasRef?.getBoundingClientRect();
  const canvasWidth = this.canvasWidth;
  const canvasHeight = this.canvasHeight;
  const widgetWidth = newWidget.options.width || 100;
  const widgetHeight = newWidget.options.height || 100;
  
  // 检查组件尺寸是否适合容器
  if (widgetWidth > canvasWidth || widgetHeight > canvasHeight) {
    this.$message.warning('组件尺寸大于容器，将自动调整大小');
    newWidget.options.width = Math.min(widgetWidth, canvasWidth);
    newWidget.options.height = Math.min(widgetHeight, canvasHeight);
  }
  
  // 设置位置
  if (position && canvasRect) {
    // 计算相对于模块画布的坐标
    let x = position.x - canvasRect.left;
    let y = position.y - canvasRect.top;
    
    // 转换为设计器坐标
    x = Math.round(x / (scale || 1));
    y = Math.round(y / (scale || 1));
    
    // 确保组件不会超出模块画布边界（使用调整后的尺寸）
    const adjustedWidth = newWidget.options.width;
    const adjustedHeight = newWidget.options.height;
    x = Math.max(0, Math.min(x, canvasWidth - adjustedWidth));
    y = Math.max(0, Math.min(y, canvasHeight - adjustedHeight));
    
    newWidget.options.x = x;
    newWidget.options.y = y;
  } else {
    // 默认位置
    newWidget.options.x += 20;
    newWidget.options.y += 20;
    
    // 确保组件不会超出模块画布边界（使用调整后的尺寸）
    const adjustedWidth = newWidget.options.width;
    const adjustedHeight = newWidget.options.height;
    newWidget.options.x = Math.max(0, Math.min(newWidget.options.x, canvasWidth - adjustedWidth));
    newWidget.options.y = Math.max(0, Math.min(newWidget.options.y, canvasHeight - adjustedHeight));
  }
  
  // 设置父模块信息
  newWidget.options.parentId = this.widget.id;
  newWidget.options.baseId = this.widget.options.id;
  
  // 添加到模块内部
  this.widget.widgetList.push(newWidget);
  this.$message.success('粘贴成功');
  
  // 复制后自动选中新粘贴的组件
  this.designer.setSelected(newWidget);
  
  // 更新剪贴板为当前粘贴的组件（便于连续粘贴）
  this.copyWidget(newWidget);
  
  this.designer.emitHistoryChange();
},

  // 处理模块内部组件的复制
  copyWidgetListForModule(copyWidgetList, parentModule) {
    copyWidgetList.forEach((widget) => {
      widget.id = widget.type.replace(/-/g, '') + generateId();

      let lastId = this.designer.getLastId();
      widget.options.id = lastId;
      widget.options.name = `${widget.type}${lastId}`;

      if (widget.options.userId) {
        widget.options.userId = this.designer.getLastUserId();
      }

      // 设置父模块ID
      widget.options.parentId = parentModule.id;
      widget.options.baseId = parentModule.options.id;

      // 递归处理子组件
      if (widget.widgetList) {
        this.copyWidgetListForModule(widget.widgetList, parentModule);
      }
    });
  },
    // 添加调试方法
  logDesignerInfo() {
    console.group('Module Designer Info');
    console.log('Designer ID:', this.designerId);
    console.log('Parent Designer ID:', this.designer?.id);
    console.log('Widget Children:', this.widgetChildren.length);
    console.log('Clipboard:', this.clipboard);
    console.groupEnd();
  },
    handleKeyDown(event) {
  // 检查是否在代码编辑区（如textarea或contenteditable元素）
  const activeElement = document.activeElement;
  const isInCodeEditor = activeElement.tagName === 'TEXTAREA' ||
    activeElement.tagName === 'INPUT' ||
    activeElement.isContentEditable;

  if (isInCodeEditor) {
    return; // 如果在代码编辑区，不处理快捷键
  }

  // 检查 Ctrl 键
  if (event.ctrlKey) {
    event.preventDefault(); // 阻止默认行为
    
    // 防止快速重复操作
    const now = Date.now();
    if (now - this.lastKeyTime < 100) return;
    this.lastKeyTime = now;

    switch (event.key.toLowerCase()) {
      case 'c':
        //this.copyWidget();
        break;
      case 'v':
        // 只通过键盘事件处理粘贴，不触发 pasteWidget 事件
        //this.pasteWidgetFromClipboard();
        break;
    }
  }
},
    // 修改复制方法，同步到全局剪贴板
  copyWidget(widget = null) {
    const widgetToCopy = widget || this.selectedWidget;
    if (!widgetToCopy) {
      this.$message.error('请先选择组件');
      return;
    }
    
    // 深拷贝组件
    const widgetCopy = deepClone(widgetToCopy);
    
    // 同时设置到designer和本地clipboard
    if (this.originalCopyMethod) {
      this.originalCopyMethod.call(this.designer, widgetCopy);
    }
    
    this.clipboard = {
      widget: widgetCopy,
      timestamp: Date.now(),
      source: 'module' // 标记来源为模块
    };
    
    // 同步到全局剪贴板
    const parentInstance = this.getParentDesignerInstance();
    if (parentInstance) {
      parentInstance.globalClipboard = deepClone(this.clipboard);
    }
    
    console.log('模块内复制成功并同步到全局:', this.clipboard);
  },

 pasteWidget(position) {
    this.pasteWidgetInModule(position, 1);
  },

// 新增方法：递归更新widgetList中的所有userId
updateWidgetListUserIds(widgetList) {
  widgetList.forEach(widget => {
    if (widget.options.userId) {
      widget.options.userId = this.designer.getLastUserId();
    }
    if (widget.widgetList) {
      this.updateWidgetListUserIds(widget.widgetList);
    }
  });
},


    // 从剪贴板中粘贴组件到画布上
  // 修改 pasteWidgetFromClipboard 方法
pasteWidgetFromClipboard() {
  // 防止快速重复粘贴（500ms内）
  const now = Date.now()
  if (now - this.lastPasteTime < 500) return
  this.lastPasteTime = now
  
  if (!this.clipboard) return
  
  // 添加防重入检查
  if (this._isPasting) return
  this._isPasting = true
  
  try {
    const widget = this.designer.copyNewFieldWidget(this.clipboard)
    const offset = 10
    
    // 使用Module组件的画布尺寸而不是全局画布
    const canvasWidth = this.canvasWidth
    const canvasHeight = this.canvasHeight
    
    // 获取鼠标在Module画布内的相对位置
    const canvasRect = this.$refs.widgetCanvasRef.getBoundingClientRect()
    const x = this.elementX - canvasRect.left
    const y = this.elementY - canvasRect.top
    
    // 设置初始位置，确保在画布范围内
    widget.options.x = Math.max(0, Math.min(x - (this.clipboard.options.width / 2 || 0) + offset, canvasWidth - (widget.options.width || 100)))
    widget.options.y = Math.max(0, Math.min(y - (this.clipboard.options.height / 2 || 0) + offset, canvasHeight - (widget.options.height || 100)))

    this.designer.addDragWidget(widget, this.widget)
    this.updateWidgetPosition(widget)
    this.designer.drag(null)
    this.designer.emitHistoryChange()
  } finally {
    this._isPasting = false
  }
},
    //选中
    selectNode(index) {
      // console.log(index)
      // console.log(this.designer)
      console.log(this.widgetChildren[index])

      this.designer.selectedWidget = this.widgetChildren[index]
    },

    delNode(index) {
      this.$confirm('是否继续删除?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.widgetChildren.splice(index, 1)
      })

    },


    widgetPropDisabled(editorName) {
      if (editorName === 'scrollHeight-editor' || editorName === 'scrollWidth-editor') {
        return false
      }

      if (this.selectedWidget.id === this.widget.id) {
        return true
      }

      return false
    },
    canvasClickHandler() {
      // console.log('canvasClickHandler---');
      this.designer.setSelected(this.widget)
    },
     // 在module-edit/index.vue中
onContextMenu(event) {
  event.preventDefault();
  
  // 获取点击位置的元素
  const clickedElement = document.elementFromPoint(event.clientX, event.y);
  const widgetElement = clickedElement.closest('.widget-item');
  
  let selectedWidget = null;
  if (widgetElement) {
    // 如果点击的是组件，选中它
    const widgetId = widgetElement.dataset.widgetId;
    selectedWidget = this.widgetChildren.find(w => w.id === widgetId);
    if (selectedWidget) {
      this.designer.setSelected(selectedWidget);
    }
  } else {
    // 如果点击的是空白区域，取消选中
    this.designer.setSelected(null);
  }
  
  // 计算是否有可粘贴的内容
  const hasClipboard = !!this.clipboard || !!this.designer?.copyWidget;
  
  // 发射菜单事件
  this.$emitter.emit('showContextMenu', {
    clientX: event.clientX,
    clientY: event.clientY,
    designerId: this.designerId,
    hasSelection: !!selectedWidget, // 是否有选中的组件
    hasClipboard, // 是否有可粘贴的内容
    isModule: true,
    context: this
  });
},
    onDragOver(evt) {
      // console.log('onDragOver---');
      evt.preventDefault()

      const widget = this.designer.dragWidget
      if (this.$refs[widget.id] && this.$refs[widget.id].length > 0) {
        const translateX = this.elementX - widget.options.x - widget.offset.x
        const translateY = this.elementY - widget.options.y - widget.offset.y

        const widgetInstance = this.$refs[widget.id][0]
        widgetInstance.$el.style.transform = `translate(${translateX}px, ${translateY}px)`
      }
    },

    onDrop(evt) {
  evt.preventDefault();
  
  if (evt.dataTransfer.effectAllowed === 'copy') {
    const widget = this.designer.dragWidget;
    
    // 检查组件是否适合容器
    const containerWidth = this.canvasWidth;
    const containerHeight = this.canvasHeight;
    const widgetWidth = widget.options.width || 100;
    const widgetHeight = widget.options.height || 100;
    
    if (widgetWidth > containerWidth || widgetHeight > containerHeight) {
      this.$message.warning('组件尺寸大于容器，将自动调整大小');
      widget.options.width = Math.min(widgetWidth, containerWidth);
      widget.options.height = Math.min(widgetHeight, containerHeight);
    }
    
    this.designer.addDragWidget(widget, this.widget);
    this.updateWidgetPosition(widget);
    this.designer.drag(null);
    this.designer.emitHistoryChange();
  }
},

    handleDragEnd(widget) {
      // console.log('handleDragEnd---')
      if (this.designer.hasWidget(widget, this.widget.widgetList)) {
        this.updateWidgetPosition(widget)

        if (this.$refs[widget.id] && this.$refs[widget.id].length > 0) {
          const widgetInstance = this.$refs[widget.id][0]
          widgetInstance.$el.style.transform = `translate(0, 0)`
        }

        // 清除拖拽元素
        this.designer.drag(null)
        // 保存操作历史
        this.designer.emitHistoryChange()
      }
    },

    handleFieldWidgetClone(origin) {
      // console.log('handleFieldWidgetClone---')
      return this.designer.copyNewFieldWidget(origin, this.widget)
    },
    onComponentDragStart(widget, evt) {
      // console.log('onComponentDragStart---')
      const widgetCopy = this.designer.copyNewFieldWidget(widget)
      widgetCopy.offset = {
        x: evt.offsetX,
        y: evt.offsetY
      }
      this.designer.drag(widgetCopy)
      evt.dataTransfer.effectAllowed = 'copy'
    },
    onComponentDragOver(evt) {
      // console.log('onComponentDragOver---')
      evt.preventDefault()
    },
    addFieldByDbClick(widget) {
      // console.log('addFieldByDbClick---')
      this.designer.addFieldByDbClick(widget, this.widget)
    },

    reRenderHorizontalRuler(width) {
      // console.log('reRenderHorizontalRuler---')
      if (this.hRuler) {
        this.$refs.horizontalRuler.removeChild(this.$refs.horizontalRuler.querySelector('canvas'))
        this.hRuler = null
      }

      this.hRuler = new Ruler(this.$refs.horizontalRuler, {
        type: 'horizontal',
        width: width + 30,
        height: 30,
        backgroundColor: '#daeaff',
        lineColor: '#000000',
        textColor: '#154a93',
        textAlign: 'right'
      })
    },
    reRenderVerticalRuler(height) {
      // console.log('reRenderVerticalRuler---')
      if (this.vRuler) {
        this.$refs.verticalRuler.removeChild(this.$refs.verticalRuler.querySelector('canvas'))
        this.vRuler = null
      }
      this.vRuler = new Ruler(this.$refs.verticalRuler, {
        type: 'vertical',
        width: 30,
        height: height + 30,
        backgroundColor: '#daeaff',
        lineColor: '#000000',
        textColor: '#154a93'
      })
    },
    getWidgetName(widget) {
      return widget.type + '-widget'
    },

    updateWidgetPosition(widget) {
  if (!widget) return;

  this.$nextTick(() => {
    if (widget.offset) {
      // 获取容器尺寸
      const containerWidth = this.canvasWidth;
      const containerHeight = this.canvasHeight;
      
      // 获取组件尺寸（带默认值）
      const widgetWidth = widget.options.width || 100;
      const widgetHeight = widget.options.height || 100;

      // 计算边界安全的位置
      let newX = this.elementX - widget.offset.x;
      let newY = this.elementY - widget.offset.y;

      // 确保组件不超出容器边界
      newX = Math.max(0, Math.min(newX, containerWidth - widgetWidth));
      newY = Math.max(0, Math.min(newY, containerHeight - widgetHeight));

      // 应用四舍五入后的位置
      widget.options.x = Math.round(newX);
      widget.options.y = Math.round(newY);
      
      // 如果组件过大则自动调整
      if (widgetWidth > containerWidth) {
        widget.options.width = containerWidth;
        this.$message.warning('组件宽度已调整以适应容器');
      }
      if (widgetHeight > containerHeight) {
        widget.options.height = containerHeight;
        this.$message.warning('组件高度已调整以适应容器');
      }

      delete widget.offset;
    }
  });
},

    getWidgetRef(widgetName, showError = false) {
      let foundRef = this.widgetRefList[widgetName]
      if (!foundRef && !!showError) {
        this.$message.error(this.i18nt('designer.hint.refNotFound') + widgetName)
      }
      return foundRef
    },

    clearWidgetRefList() {
      // console.log('clearWidgetRefList---')
      Object.keys(this.widgetRefList).forEach((widgetRef) => {
        delete this.widgetRefList[widgetRef]
      })
    },

    deleteWidgetRef(widgetRefName) {
      // console.log('deleteWidgetRef---')
      delete this.widgetRefList[widgetRefName]
    },

    editEventHandler(eventName) {
  this.curEventName = eventName;
  this.eventHandlerCode = this.selectedWidget.options[eventName] || '';
  this.showWidgetEventDialogFlag = true;

  this.$nextTick(() => {
    const editor = this.$refs.ecEditor?.aceEditor;
    if (editor) {
      editor.container.style.height = "350px";  // 直接修改 DOM
      editor.resize();  // 强制 ACE Editor 重新计算布局
    }
  });
},
    handleWidgetPreview() {
  // 先保存代码但不关闭对话框
  this.saveEventHandler(false).then((success) => {
    if (success) {
      // 触发页面仿真
      this.$emitter.emit('CLEAR_DEBUG_LOG')
      this.$emitter.emit(
        'START_PAGE_DEBUG',
        (this.designer && this.designer.options.name) || ''
      )
    }
  })
},

    saveEventHandler(closeDialog = true) {
  return new Promise((resolve) => {
    const codeHints = this.$refs.ecEditor.getEditorAnnotations()
    let syntaxErrorFlag = false
    if (!!codeHints && codeHints.length > 0) {
      codeHints.forEach((chItem) => {
        if (chItem.type === 'error') {
          syntaxErrorFlag = true
        }
      })

      if (syntaxErrorFlag) {
        this.$message.error(this.i18nt('designer.setting.syntaxCheckWarning'))
        resolve(false)
        return
      }
    }

    this.selectedWidget.options[this.curEventName] = this.eventHandlerCode
    if (closeDialog) {
      this.showWidgetEventDialogFlag = false
    }
    resolve(true)
  })
},
  }
}
</script>

<style lang="scss" scoped>
.code-editor-dialog {
  :deep(.ace-container) {
    height: 300px !important;
  }
  :deep(.ace-editor) {
    min-height: 200px !important;
    height: 300px !important;
  }
}
.variable-info {
  padding: 5px 12px;
  margin-bottom: 5px;
  background-color: #f5f7fa;
  border-radius: 8px;
  border-left: 4px solid #409eff;
  font-size: 12px;
  color: #606266;
}
.selectNodeCls {
  background: #f0d292;
}

.baseNodeCls {
  padding: 6px 15px;
  box-sizing: border-box;
  font-size: 12px;
  display: grid;
  grid-template-columns: 3fr 1fr;

  &:hover {
    cursor: pointer;
  }
}

.widget-edit-container {
  position: relative;

  :deep(.el-card) {
    margin-top: 0;

    .el-card__header {
      background-color: #daeaff;
      color: #083772;
      font-size: 12px;
      padding: 10px 15px;
    }

    .el-card__body {
      padding: 4px;
      border: #6593cf solid 1px;
    }
  }

  .aside-left {
    width: 180px;

    ul {
      padding-left: 10px;
      /* 重置IE11默认样式 */
      margin: 0;
      /* 重置IE11默认样式 */
      margin-block-start: 0;
      margin-block-end: 0.25em;
      padding-inline-start: 10px;

      &:after {
        content: '';
        display: block;
        clear: both;
      }

      .field-widget-item {
        display: inline-block;
        height: 24px;
        line-height: 24px;
        font-size: 11px;
        width: 98px;
        margin: 2px 6px 6px 0;
        cursor: move;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
        background: #fff;
        border: 1px solid #e8e9eb;
        border-radius: 4px;
        padding: 0 8px;

        &:hover {
          background: #ffeaa6;
          border-color: #e49c05;
          color: $--color-primary;

          .color-svg-icon {
            color: $--color-primary;
          }
        }
      }

      .field-widget-item.field-widget-item-disabled {
        color: #808080;
        cursor: not-allowed;

        &:hover {
          background: #e8e9eb;
          border-color: #e8e9eb;

          .color-svg-icon {
            color: #808080;
            fill: #808080;
          }
        }
      }
    }
  }

  .widget-edit-main {
    padding-top: 0;
    padding-bottom: 0;

    .widget-designer-scroll {
      .widget-designer {
        position: relative;
        background: #daeaff;
        overflow: hidden;

        .ruler {
          position: absolute;
          top: 0;
          left: 0;
        }

        .ruler.horizontal-ruler {
          left: 30px;
          right: 0;
        }

        .ruler.vertical-ruler {
          top: 30px;
          bottom: 0;
        }

        .widget-canvas-cantainer {
          position: absolute;
          left: 30px;
          right: 30px;
          top: 30px;
          bottom: 30px;
          background: #ffffff;

          :deep(.el-row) {
            padding: 2px;
            border: 1px dashed rgba(170, 170, 170, 0.75);
          }
        }
      }
    }
  }

  .aside-right {
    width: 300px;

    .setting-form {
      padding: 0 6px;

      :deep(.el-form-item__label) {
        font-size: 11px;
        overflow: hidden;
        white-space: nowrap;
      }

      :deep(.el-form-item--small.el-form-item) {
        margin-bottom: 10px;
      }

      :deep(.el-slider) {
        .el-slider__runway {
          margin-right: 16px;
        }

        .el-slider__input {
          width: 85px !important;
        }
      }

      :deep(.el-select) {
        width: 178px !important;
      }
    }
  }
}
</style>
